#include "Character.h"
#include <stdlib.h>
#include <time.h>

Character::Character() :
	strengthValue(0),
	strengthCounters(0),
	craftCounters(0),
	craftValue(0),
	lifeCounters(0),
	lifeValue(0),
	fateTokens(0),
	fateValue(0),
	gold(0),
	isDead(false)
{
	observers.clear();
}

Character::Character(int _strengthValue, int _strengthCounters, int _craftCounters, int _craftValue, int _lifeCounters, int _lifeValue, int _fateTokens, int _fateValue, int _gold) 
	: strengthValue(_strengthValue),
	strengthCounters(_strengthCounters),
	craftCounters(_craftCounters),
	craftValue(_craftValue),
	lifeCounters(_lifeCounters),
	lifeValue(_lifeValue),
	fateTokens(_fateTokens),
	fateValue(_fateValue),
	gold(_gold),
	isDead(false)
{
	observers.clear();
}


void Character::registerOb(Observer* ob)
{
	observers.push_back(ob);
}
void Character::removeOb(Observer* ob)
{
	observers.remove(ob);
}
void Character::notify()
{
	list<Observer*>::iterator pos = observers.begin();
        while (pos != observers.end())
        {
            ((Observer* )(*pos))->update();
            ++pos;
        }
}
void Character::dataChange(int str, int cr, int fa, int li, int go)
{
	//For sake of simplicity in calculating Strength, Craft, and Fate, we just display the strengthValue as Strength and so on, so it makes it easier to alter the data for the example

	strengthValue = str;
	strengthCounters = 0;
	craftValue = cr;
	craftCounters = 0;
	fateValue = fa;
	fateTokens = 0;
	lifeCounters = li;
	gold = go;
	notify();
}
//***************** STRENGTH *****************

//Losing Strength: remove Strength Counter, A Character's Strength may never drop below the Character's Strength Value
void Character::loseStrength()
{
	if (getStrength() > strengthValue)
		strengthCounters--;

}

//Gaining Strength Counters during play
void Character::gainStrength(int s)
{
	strengthCounters += s;
}

//Strength at any given time is Strength Value + Strength Counters + Strength from Objects, Magic Objects and Followers 
//that may be used at that time
int Character::getStrength()
{
	return (strengthCounters + strengthValue);
}
//***************** STRENGTH *****************

//***************** CRAFT *****************
void Character::loseCraft()
{
	if (getCraft() > craftValue)
		craftCounters--;
}

void Character::gainCraft(int c)
{
	craftCounters += c;
}

int Character::getCraft()
{
	return (craftValue + craftCounters);
}
//***************** CRAFT *****************

//***************** LIVES *****************

//If all lives are lost, call killCharacter to handle the death event
void Character::loseLife()
{
	if (!isDead)
	{
		lifeCounters--;
		if (lifeCounters == 0)
		{
			killCharacter();
		}
	}
		
}

void Character::gainLife(int l)
{
	if (!isDead)
		lifeCounters += l;
}

//Healing replenishes life to the Character's life value
void Character::heal()
{
	if (lifeCounters < lifeValue)
		lifeCounters = lifeValue;
}

int Character::getLives()
{
	return lifeCounters;
}

void Character::killCharacter()
{
	isDead = true;
	strengthCounters = 0;
	craftCounters = 0;
	fateTokens = 0;
	gold = 0;
	//TODO: Objects, Magic Object, Followers, 
	// Spell Cards, and any other cards or counters
}

//***************** LIVES *****************

//***************** TOKENS *****************

//Pay a Fate Token to reroll, if no Fate Tokens left, indicate that a reroll will not be permitted;
bool Character::payToken()
{
	if (fateTokens != 0)
	{
		fateTokens--;
		return true;
	}
	else
	{
		return false;
	}
}

//Replenish to fate value
void Character::replenishFate()
{
	if (fateTokens < fateValue)
		fateTokens = fateValue;
}

void Character::gainFate(int f)
{
	fateTokens += f;
}

int Character::getFate()
{
	return (fateTokens + fateValue);
}

//***************** GOLD *****************

void Character::loseGold(int g)
{
	if (g > gold)
		gold = 0;
	else
		gold -= g;

}
void Character::gainGold(int g)
{
	gold += g;
}

int Character::getGold()
{
	return gold;
}

//***************** BATTLE *****************
int Character::attackRoll()
{
	srand(time(NULL));
	int roll = rand() % 6 + 1;
	return roll + getStrength(); // + any other modifiers from Weapons and such
}

//***************** GAMEPLAY *****************
int Character::moveRoll()
{
	return rand() % 6 + 1;
}

void Character::announce()
{
	cout << "Generic Character class announce function called!!!" << endl;
}